/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file    adc.c
 * @brief   This file provides code for the configuration
 *          of the ADC instances.
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2024 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "adc.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

ADC_HandleTypeDef hadc;
DMA_HandleTypeDef hdma_adc;

/* ADC init function */
void MX_ADC_Init(void)
{

    /* USER CODE BEGIN ADC_Init 0 */

    /* USER CODE END ADC_Init 0 */

    ADC_ChannelConfTypeDef sConfig = {0};

    /* USER CODE BEGIN ADC_Init 1 */

    /* USER CODE END ADC_Init 1 */

    /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
     */
    hadc.Instance = ADC1;
    hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
    hadc.Init.Resolution = ADC_RESOLUTION_12B;
    hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
    hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    hadc.Init.LowPowerAutoWait = DISABLE;
    hadc.Init.LowPowerAutoPowerOff = DISABLE;
    hadc.Init.ContinuousConvMode = DISABLE;
    hadc.Init.DiscontinuousConvMode = DISABLE;
    hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc.Init.DMAContinuousRequests = DISABLE;
    hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
    if (HAL_ADC_Init(&hadc) != HAL_OK)
    {
        Error_Handler();
    }

    /** Configure for the selected ADC regular channel to be converted.
     */
    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
    sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
    if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
    {
        Error_Handler();
    }

    /** Configure for the selected ADC regular channel to be converted.
     */
    sConfig.Channel = ADC_CHANNEL_1;
    if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
    {
        Error_Handler();
    }

    /** Configure for the selected ADC regular channel to be converted.
     */
    sConfig.Channel = ADC_CHANNEL_3;
    if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
    {
        Error_Handler();
    }
    /* USER CODE BEGIN ADC_Init 2 */

    /* USER CODE END ADC_Init 2 */
}

void HAL_ADC_MspInit(ADC_HandleTypeDef *adcHandle)
{

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if (adcHandle->Instance == ADC1)
    {
        /* USER CODE BEGIN ADC1_MspInit 0 */

        /* USER CODE END ADC1_MspInit 0 */
        /* ADC1 clock enable */
        __HAL_RCC_ADC1_CLK_ENABLE();

        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**ADC GPIO Configuration
        PA0     ------> ADC_IN0
        PA1     ------> ADC_IN1
        PA3     ------> ADC_IN3
        */
        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3;
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        /* ADC1 DMA Init */
        /* ADC Init */
        hdma_adc.Instance = DMA1_Channel1;
        hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
        hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
        hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
        hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
        hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
        hdma_adc.Init.Mode = DMA_CIRCULAR;
        hdma_adc.Init.Priority = DMA_PRIORITY_LOW;
        if (HAL_DMA_Init(&hdma_adc) != HAL_OK)
        {
            Error_Handler();
        }

        __HAL_LINKDMA(adcHandle, DMA_Handle, hdma_adc);

        /* ADC1 interrupt Init */
        HAL_NVIC_SetPriority(ADC1_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(ADC1_IRQn);
        /* USER CODE BEGIN ADC1_MspInit 1 */

        /* USER CODE END ADC1_MspInit 1 */
    }
}

void HAL_ADC_MspDeInit(ADC_HandleTypeDef *adcHandle)
{

    if (adcHandle->Instance == ADC1)
    {
        /* USER CODE BEGIN ADC1_MspDeInit 0 */

        /* USER CODE END ADC1_MspDeInit 0 */
        /* Peripheral clock disable */
        __HAL_RCC_ADC1_CLK_DISABLE();

        /**ADC GPIO Configuration
        PA0     ------> ADC_IN0
        PA1     ------> ADC_IN1
        PA3     ------> ADC_IN3
        */
        HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3);

        /* ADC1 DMA DeInit */
        HAL_DMA_DeInit(adcHandle->DMA_Handle);

        /* ADC1 interrupt Deinit */
        HAL_NVIC_DisableIRQ(ADC1_IRQn);
        /* USER CODE BEGIN ADC1_MspDeInit 1 */

        /* USER CODE END ADC1_MspDeInit 1 */
    }
}

/* USER CODE BEGIN 1 */
/*
u16 getBatVoltage(void) {
    u8 i = 0;
    u16 BATVAL = 0;
    float VDDA = 0;
    float VCHANNELx = 0;  // 实际测量的电池电量�??
    __IO u16 VREFINT_CAL = 0;
    VREFINT_CAL = *(__IO u16*)(0x1FF80078);  // 得到�??�??16进制的校准�??

    printf("\n\r ***** START PRINTF ADC INFO ******** \r\n\n");
    for (i = 0; i < ADC_CHANNEL_CNT; i++) {
        printf(
            "ADC1[%02d] Sampling voltage = %1.3f V Sampling value = %04d\r\n",
            i, adc1_aver_val[i] * 3.0f / 4095, adc1_aver_val[i]);
    }

    VDDA = 3 * VREFINT_CAL * 1000 / adc1_aver_val[1];  // 扩大1000�??
    printf("VDDA:%lf \r\n", VDDA);
    printf("VREFINT_CAL:%d\r\n", VREFINT_CAL);
    printf("VCHANNELx: %0.4f \r\n", (float)(VDDA * adc1_aver_val[0] / 4095));

    VCHANNELx = (float)((300 * VREFINT_CAL * adc1_aver_val[0]) /
                        (adc1_aver_val[1] * 4095)) /
                100;
    // printf("VCHANNELx: %0.4f \r\n",VCHANNELx);
    BATVAL = (VCHANNELx * 3.0 + 0.03) *
             100;  // 3.0是分压电阻检测ADC的系�??,
                   // 0.03是跟实际少的差�??100是放大一百�??
    //	printf("BATVAL: %d \r\n",BATVAL);
    printf("g_BatVoltage: %d \r\n", BATVAL);
    return BATVAL;
}
*/

// u16 getChipInTempVal(void)  // 获取芯片内部温度
//{
//     u16 tempVal = 0;
//     tempVal = (V25 - adc1_aver_val[2]) / AVG_SLOPE + 25;

//    printf("adc1_aver_val[2]: %d, Temp:%3d �?? \r\n", adc1_aver_val[2], tempVal);
//    return tempVal;
//}

// void get_ADC_Channel_Val(void) {
//     u8 i = 0;
//     // 1ms进入中断
//     /* 清除adc采样平均值变�?? */
//     for (i = 0; i < ADC_CHANNEL_CNT; i++) {
//         adc1_aver_val[i] = 0;
//     }
//     /* 在采样�?�数组中分别取出每个通道的采样�?�并求和 */
//     for (i = 0; i < ADC_CHANNEL_FRE; i++) {
//         adc1_aver_val[0] += adc1_val_buf[i * 3 + 0];
//         adc1_aver_val[1] += adc1_val_buf[i * 3 + 1];
//         adc1_aver_val[2] += adc1_val_buf[i * 3 + 2];
//     }
//     /* 依次对每个�?�道采样值求平均�?? */
//     for (i = 0; i < ADC_CHANNEL_CNT; i++) {
//         adc1_aver_val[i] /= ADC_CHANNEL_FRE;
//     }
// }

/* USER CODE END 1 */
